/*
 *
 * Title:UdpClient.cc
 * Time:2019-1-5
 * Athor:Liu
 *
 */

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        std::cout<<"\nError : Please Input With IP and Port\n";
        exit(1);
    }

    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sock < 0)
    {
        std::cout<<"\nError : Create Socket Failed!\n";
        exit(2);
    }

    char peerConnect[1024*10] = {0};
    struct sockaddr_in addrServer = {0};
    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(atoi(argv[2]));
    addrServer.sin_addr.s_addr = inet_addr(argv[1]);
    socklen_t len = sizeof(addrServer);

    if(-1 == sendto(sock, peerConnect, 1, 0, (struct sockaddr*)&addrServer, len))
    {
        std::cout<<"\nError : Connect to Server Failed!\n";
        close(sock);
        exit(3);
    }
    
    struct sockaddr_in addrUser = {0};
    socklen_t len2 = 0;
    if(-1 == recvfrom(sock, peerConnect, sizeof(peerConnect), \
                0, (struct sockaddr*)&addrServer, &len2))
    {
        std::cout<<"\nError : Recv Error from Server!"<<std::endl;
        close(sock);
        exit(4);
    }
    else
    {
        memcpy(&addrUser, peerConnect, sizeof(addrUser));
        sprintf(peerConnect, "\nhello, user ip=[%s], port=[%d]\n",\
                inet_ntoa(addrUser.sin_addr), htons(addrUser.sin_port));
        if(-1 == sendto(sock, peerConnect, strlen(peerConnect), 0, \
                    (struct sockaddr*)&addrUser, sizeof(addrUser)))
        {
            std::cout<<"\nError : Send to Other Client Failed!\n";
            exit(5);
        }
        else
        {
            std::cout<<"\nInfo Send to Other Client Succesful!\n";
            //memcpy(peerConnect, 0, sizeof(peerConnect));
            std::cout<<"\n Memcpy Is Ok\n";
            socklen_t ll;
            if(-1 == recvfrom(sock, peerConnect, sizeof(peerConnect), 
                        0, (struct sockaddr*)&addrUser, &ll))
            {
                std::cout<<"\nError : Filed to RecvFrom Other Client!\n";
                close(sock);
                exit(6);
            }
            std::cout<<"\nRecv From Other Client : "<<peerConnect<<std::endl;
            
            std::cout<<"\nStart to Chat With Others\n";
            
            while(1)
            {
                char buff[1024] = {0};
                std::cout<<"\nSendto : ";
                std::cin.getline(buff, 1023);
                
                sendto(sock, buff, strlen(buff), 0, \
                        (struct sockaddr*)&addrUser, sizeof(addrUser));

                recvfrom(sock, buff, sizeof(buff), 
                        0, (struct sockaddr*)&addrUser, &ll);
                std::cout<<"\nMeassage : "<<buff<<std::endl;
            }   
        }
    }
    if(sock)
        close(sock);
    return 0;
}


